﻿using System;
using System.Collections.Generic;

namespace ProLinq.Projection.Configuration
{
	/// <summary>
	///     Projection configuration
	/// </summary>
	public class ProjectionConfiguration : ICloneable
	{
		private ProjectionCollection _projections = new ProjectionCollection();

		public ProjectionConfiguration()
		{
			this.EnableOptimization = true;
			this.EnablePartialProjection = true;
		}

		/// <summary>
		/// Gets the list of configured projections.
		/// </summary>
		internal ProjectionCollection ProjectionsInternal
		{
			get { return this._projections; }
		}

		/// <summary>
		/// Gets the list of configured projections.
		/// </summary>
		public IList<Projection> Projections
		{
			get { return this._projections; }
		}

		/// <summary>
		/// Eneables partial projection on source.
		/// </summary>
		public Boolean EnablePartialProjection { get; set; }

		/// <summary>
		/// Enables query optimization in case of partial processing.
		/// </summary>
		public Boolean EnableOptimization { get; set; }

		/// <summary>
		/// True if all anonymous types should be projected. 
		/// Otherwise only those participating in other projections will be projected.
		/// </summary>
		public Boolean ForceAnonymousProjection { get; set; }

		#region ICloneable Members

		public object Clone()
		{
			// use MemberwiseClone so that 
			var cfg = (ProjectionConfiguration)this.MemberwiseClone();
			cfg.EnableOptimization = this.EnableOptimization;
			cfg.EnablePartialProjection = this.EnablePartialProjection;
			cfg.ForceAnonymousProjection = this.ForceAnonymousProjection;
			cfg._projections = new ProjectionCollection();
			foreach (var proj in ProjectionsInternal)
			{
				var clonedProj = (Projection)proj.Clone();
				cfg._projections.Add(clonedProj);
			}

			return cfg;
		}

		#endregion
	}
}